/*
 * TimeRecordingView.java
 */
package TimeRecording;

import TimeRecording.business.ClockedTime;
import TimeRecording.business.DaisyChainUtilities;
import TimeRecording.business.DateRange;
import TimeRecording.business.HolidayCalculations;
import TimeRecording.business.MonthEndCalculations;
import TimeRecording.business.PeriodCalculations;
import TimeRecording.business.SicknessCalculations;
import TimeRecording.business.TimesheetMaintenance;
import TimeRecording.enums.AuthorisationLevel;
import TimeRecording.exceptions.NoMonthEndException;
import TimeRecording.forms.BadgeDialog;
import TimeRecording.forms.ClockedTimesDialog;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

import TimeRecording.forms.EmployeesDialog;
import TimeRecording.forms.ErrorDialog;
import TimeRecording.forms.HolidayAdjustmentDialog;
import TimeRecording.forms.HolidayRequestDialog;
import TimeRecording.forms.LoginDialog;
import TimeRecording.forms.MonthEndDialog;
import TimeRecording.forms.MonthEndProcessingDialog;
import TimeRecording.forms.PublicHolidayDialog;
import TimeRecording.forms.SelectDateDialog;
import TimeRecording.forms.SelectEmployeesDialog;
import TimeRecording.forms.SicknessReportDialog;
import TimeRecording.forms.SelectDateRangeDialog;
import TimeRecording.forms.SessionsDialog;
import TimeRecording.forms.TimesheetEditor;
import TimeRecording.reporting.AbsenceIconProvider;
import TimeRecording.reporting.CalendarReport;
import TimeRecording.reporting.EmployeeSummaryReport;
import TimeRecording.reporting.CollationReport;
import TimeRecording.reporting.EndOfMonthSummary;
import TimeRecording.reporting.MonthEndSummaryReport;
import TimeRecording.reporting.AnomaliesReport;
import TimeRecording.reporting.ReportingUtilities;
import TimeRecording.tables.Control;
import TimeRecording.tables.Employee;
import TimeRecording.tables.Event;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.SimpleFormatter;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.jdesktop.application.Application;
import org.jdesktop.observablecollections.ObservableCollections;

/**
 * The application's main frame.
 */
public class TimeRecordingView extends FrameView {

    private enum HousekeepingTask {
        CLOCKED_TIME,
        TIMESHEET,
        ALLOCATED_TIME,
        HOLIDAY,
        HOLIDAY_SUMMARY,
        SICKNESS,
        SICKNESS_SUMMARY,
        MONTH_END
    };

    private final static String PROPERTIES_FILE = "TimeRecording.properties";

    private Properties props;
    private String loggingFolder;
    private Level loggingLevel;

    private final static int LOG_FILE_COUNT = 16;
    private final static int LOG_FILE_SIZE = 0x0FFFFF;

    private static FileHandler FILE_HANDLER = null;

    private final static Logger BASE_LOGGER = Logger.getLogger("");

    private final static Logger LOGGER = Logger.getLogger(
            TimeRecordingView.class.getName());


    // <editor-fold defaultstate="collapsed" desc="recordSelected + Getter & Setter">
    private boolean recordSelected = false;

    public boolean isRecordSelected() {
	recordSelected = (masterTable.getSelectedRow() != -1);
	return recordSelected;
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="loggedInEmployee + Getter & Setter">
    private Employee loggedInEmployee;

    public Employee getLoggedInEmployee() {
	return loggedInEmployee;
    }

    public void setLoggedInEmployee(Employee loggedInEmployee) {
	Employee oldloggedInEmployee = this.loggedInEmployee;
	this.loggedInEmployee = loggedInEmployee;
	firePropertyChange("loggedInEmployee", oldloggedInEmployee, loggedInEmployee);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="loggedInAuthorisationLevel + Getter & Setter">
    private AuthorisationLevel loggedInAuthorisationLevel = AuthorisationLevel.DELETED;

    public AuthorisationLevel getLoggedInAuthorisationLevel() {
	return loggedInAuthorisationLevel;
    }

    public void setLoggedInAuthorisationLevel(AuthorisationLevel loggedInAuthorisationLevel) {

	AuthorisationLevel oldLoggedInAuthorisationLevel = this.loggedInAuthorisationLevel;
	this.loggedInAuthorisationLevel = loggedInAuthorisationLevel;
	firePropertyChange("loggedInAuthorisationLevel", oldLoggedInAuthorisationLevel, loggedInAuthorisationLevel);

        // Also set supervisor logged in property
	setSupervisorLoggedIn(loggedInAuthorisationLevel == AuthorisationLevel.SUPERVISOR);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="printWatermark + Getter & Setter">
    private boolean printWatermark;

    public boolean getPrintWatermark() {
        return printWatermark;
    }

    public void setPrintWatermark(boolean printWatermark) {
        boolean oldPrintWatermark = this.printWatermark;
        this.printWatermark = printWatermark;
        firePropertyChange("printWatermark", oldPrintWatermark, printWatermark);
        props.setProperty("reporting.printWatermark", new Boolean(printWatermark).toString());
        ReportingUtilities.setSuppressWatermark(!printWatermark);
        saveProperties();
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="printGreenShading + Getter & Setter">
    private boolean printGreenShading;

    public boolean getPrintGreenShading() {
        return printGreenShading;
    }

    public void setPrintGreenShading(boolean printGreenShading) {
        boolean oldPrintGreenShading = this.printGreenShading;
        this.printGreenShading = printGreenShading;
        firePropertyChange("printGreenShading", oldPrintGreenShading, printGreenShading);
        props.setProperty("reporting.printGreenShading",
                new Boolean(printGreenShading).toString());
        saveProperties();
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="entityManager Getter & Setter">
    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        EntityManager oldEntityManager = this.entityManager;
        this.entityManager = entityManager;
        firePropertyChange("entityManager", oldEntityManager, entityManager);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="supervisorLoggedIn">
    protected boolean supervisorLoggedIn = false;

    public boolean isSupervisorLoggedIn() {
	return supervisorLoggedIn;
    }

    public void setSupervisorLoggedIn(boolean supervisorLoggedIn) {
        boolean oldSupervisorLoggedIn = this.supervisorLoggedIn;
        this.supervisorLoggedIn = supervisorLoggedIn;
	firePropertyChange("supervisorLoggedIn", oldSupervisorLoggedIn, supervisorLoggedIn);
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="eventList + Getter & Setter">
    private List<Event> eventList =
            ObservableCollections.observableList(new ArrayList<Event>());

    public List<Event> getEventList() {
        return eventList;
    }

    public void setEventList(List<Event> eventList) {
        List<Event> oldEventList = this.eventList;
        this.eventList = eventList;
        firePropertyChange("eventList", oldEventList, eventList);
    } // </editor-fold>

    @SuppressWarnings("unchecked")
    public TimeRecordingView(SingleFrameApplication app) {

	super(app);
	myApp = app;

	// perform initial login
	showLoginDialog();

	initComponents();

        loadProperties();
        setLoggingLevel(loggingLevel);
        setLoggingFolder(loggingFolder);

        getFrame().setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        entityManager = loginDialog.getEntityManager();

	ResourceMap resourceMap = getResourceMap();

	// Status bar initialization - message timeout, idle icon and busy animation, etc

        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
	messageTimer = new Timer(messageTimeout, new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		statusMessageLabel.setText("");
	    }
	});

	messageTimer.setRepeats(false);
	int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
	for (int i = 0; i < busyIcons.length; i++) {
	    busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
	}
	
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
		statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
	    }
	});

	idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
	statusAnimationLabel.setIcon(idleIcon);
	progressBar.setVisible(false);

	// Connecting action tasks to status bar via TaskMonitor

	TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
	taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

	    public void propertyChange(java.beans.PropertyChangeEvent evt) {

                String propertyName = evt.getPropertyName();
		
                if ("started".equals(propertyName)) {
		    if (!busyIconTimer.isRunning()) {
			statusAnimationLabel.setIcon(busyIcons[0]);
			busyIconIndex = 0;
			busyIconTimer.start();
		    }
		    progressBar.setVisible(true);
		    progressBar.setIndeterminate(true);

		} else if ("done".equals(propertyName)) {
		    busyIconTimer.stop();
		    statusAnimationLabel.setIcon(idleIcon);
		    progressBar.setVisible(false);
		    progressBar.setValue(0);

		} else if ("message".equals(propertyName)) {
		    String text = (String) (evt.getNewValue());
		    statusMessageLabel.setText((text == null) ? "" : text);
		    messageTimer.restart();

		} else if ("progress".equals(propertyName)) {
		    int value = (Integer) (evt.getNewValue());
		    progressBar.setVisible(true);
		    progressBar.setIndeterminate(false);
		    progressBar.setValue(value);
		}
	    }
	});

	// Tracking table selection
	masterTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    firePropertyChange("recordSelected", !isRecordSelected(), isRecordSelected());
                }
        });

        getFrame().addWindowListener(new WindowAdapter() {
            
                @Override
                public void windowOpened(WindowEvent e) {

                    super.windowOpened(e);

                    e.getWindow().setSize(1100, 400);

                    Dimension screenDims = e.getWindow().getToolkit().getScreenSize();
                    Rectangle frameDims = e.getWindow().getBounds();
                    
                    e.getWindow().setLocation(
                            (screenDims.width - frameDims.width) / 2,
                            (screenDims.height - frameDims.height) / 2);
                }
        });

	// Display appropriate events in the table
	showAllEvents();

        // TODO: Finally, perform a bit of housekeeping (this
        // will need to be moved into scheduled housekeeping).

//        if (isSupervisorLoggedIn()) {
//            performHousekeeping();
//        }
    }

    public Application getMyApplication() {
	return myApp;
    }

    @Action
    public void showAboutBox() {
	if (aboutBox == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    aboutBox = new TimeRecordingAboutBox(mainFrame);
	    aboutBox.setLocationRelativeTo(mainFrame);
	}
	TimeRecordingApp.getApplication().show(aboutBox);
    }

    @Action
    public void showEmployeesDialog() {
	if (employeesDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    employeesDialog = new EmployeesDialog(this, false);
	    employeesDialog.setLocationRelativeTo(mainFrame);
	}
        
        boolean isVisible = employeesDialog.isVisible();
	employeesToggle.setSelected(!isVisible);
        employeesDialog.setVisible(!isVisible);
    }

    public void hideEmployeesDialog() {

        employeesToggle.setSelected(false);
	employeesDialog.setVisible(false);
//	employeesDialog.dispose();
//	employeesDialog = null;

	// Update events list with any new events
	showAllEvents();
    }

    /**
     * Toggles display of the badges dialog and sets the toggle button on the
     * main dialog as appropriate.  This option is only available to supervisors.
     */
    @Action(enabledProperty = "supervisorLoggedIn")
    public void showBadgesDialog() {
        
	if (badgesDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    badgesDialog = new BadgeDialog(this, false);
	    badgesDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = badgesDialog.isVisible();
	badgesToggle.setSelected(!isVisible);
        badgesDialog.setVisible(!isVisible);
    }

    public void hideBadgesDialog() {

        badgesToggle.setSelected(false);
	badgesDialog.setVisible(false);
//	badgesDialog.dispose();
//	badgesDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    @Action
    public void showTimesheetsDialog() {

	if (timesheetsDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    timesheetsDialog = new TimesheetEditor(this, entityManager, false);
	    timesheetsDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = timesheetsDialog.isVisible();
	timesheetsToggle.setSelected(!isVisible);
        timesheetsDialog.setVisible(!isVisible);
    }

    public void hideTimesheetsDialog() {

	timesheetsToggle.setSelected(false);
        timesheetsDialog.setVisible(false);
//	timesheetsDialog.dispose();
//	timesheetsDialog = null;

	// Update events list with any new events
	showAllEvents();
    }

    @Action
    public void showHolidayRequestDialog() {

	if (holidayRequestDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    holidayRequestDialog = new HolidayRequestDialog(this, false);
	    holidayRequestDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = holidayRequestDialog.isVisible();
	holidayRequestToggle.setSelected(!isVisible);
        holidayRequestDialog.setVisible(!isVisible);
    }

    public void hideHolidayRequestDialog() {

        holidayRequestToggle.setSelected(false);
	holidayRequestDialog.setVisible(false);
//	holidayRequestDialog.dispose();
//	holidayRequestDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    @Action
    public void showHolidayAdjustmentDialog() {

	if (holidayAdjustmentDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    holidayAdjustmentDialog = new HolidayAdjustmentDialog(this, entityManager, false);
	    holidayAdjustmentDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = holidayAdjustmentDialog.isVisible();
	holidayAdjustmentToggle.setSelected(!isVisible);
        holidayAdjustmentDialog.setVisible(!isVisible);
    }

    public void hideHolidayAdjustmentDialog() {

        holidayAdjustmentToggle.setSelected(false);
        holidayAdjustmentDialog.setVisible(false);
//	holidayAdjustmentDialog.dispose();
//	holidayAdjustmentDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    @Action
    public void showSicknessDialog() {

	if (sicknessReportDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    sicknessReportDialog = new SicknessReportDialog(this, entityManager, false);
	    sicknessReportDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = sicknessReportDialog.isVisible();
	sicknessReportToggle.setSelected(!isVisible);
        sicknessReportDialog.setVisible(!isVisible);
    }

    public void hideSicknessDialog() {

        sicknessReportToggle.setSelected(false);
	sicknessReportDialog.setVisible(false);
//	sicknessReportDialog.dispose();
//	sicknessReportDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    /**
     * Toggles display of the badges dialog and sets the toggle button on the
     * main dialog as appropriate.  This option is only available to supervisors.
     */
    @Action(enabledProperty = "supervisorLoggedIn")
    public void showMonthEndDialog() {

	if (monthEndDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();

            try {
                monthEndDialog = new MonthEndDialog(this, entityManager);
                
            } catch (NoMonthEndException e) {
                monthEndDialog = null;
        	monthEndToggle.setSelected(false);
                return;
            }
            
            monthEndDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = monthEndDialog.isVisible();
	monthEndToggle.setSelected(!isVisible);
        monthEndDialog.setVisible(!isVisible);
    }

    public void hideMonthEndDialog() {

        monthEndToggle.setSelected(false);
	monthEndDialog.setVisible(false);
//	monthEndDialog.dispose();
//	monthEndDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    /**
     * Toggles display of the badges dialog and sets the toggle button on the
     * main dialog as appropriate.  This option is only available to supervisors.
     */
    @Action(enabledProperty = "supervisorLoggedIn")
    public void showSessionsDialog() {

	if (sessionsDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
            sessionsDialog = new SessionsDialog(this, entityManager, false);
            sessionsDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = sessionsDialog.isVisible();
	sessionsToggle.setSelected(!isVisible);
        sessionsDialog.setVisible(!isVisible);
    }

    public void hideSessionsDialog() {

        sessionsToggle.setSelected(false);
	sessionsDialog.setVisible(false);
//	sessionsDialog.dispose();
//	sessionsDialog = null;

        // Update events list with any new events
	showAllEvents();
    }


    @Action(enabledProperty = "supervisorLoggedIn")
    public void showClockedTimesDialog() {

        if (clockedTimesDialog == null) {
	    JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
	    clockedTimesDialog = new ClockedTimesDialog(this, entityManager);
	    clockedTimesDialog.setLocationRelativeTo(mainFrame);
	}

        boolean isVisible = clockedTimesDialog.isVisible();
	clockedTimesToggle.setSelected(!isVisible);
        clockedTimesDialog.setVisible(!isVisible);
    }

    public void hideClockedTimesDialog() {

        clockedTimesToggle.setSelected(false);
	clockedTimesDialog.setVisible(false);
//	clockedTimesDialog.dispose();
//	clockedTimesDialog = null;

        // Update events list with any new events
	showAllEvents();
    }

    @Action
    public void showPublicHolidayDialog() {
        JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();
        PublicHolidayDialog dialog = new PublicHolidayDialog(this);
        dialog.setLocationRelativeTo(mainFrame);
        dialog.setVisible(true);
    }

    public void hidePublicHolidayDialog() {

    }
    @Action
    public void logout() {
        System.exit(0);
    }

    @Action
    public void showLoginDialog() {

	// Show login dialog before displaying anything else
	JFrame mainFrame = TimeRecordingApp.getApplication().getMainFrame();

	setLoggedInAuthorisationLevel(AuthorisationLevel.DELETED);
	setLoggedInEmployee(null);

	bLoggedIn = false;
	while (!bLoggedIn) {

	    loginDialog = new LoginDialog(getFrame(), true);
	    loginDialog.setLocationRelativeTo(mainFrame);
	    loginDialog.setVisible(true);

	    // Back, check properties
	    if (loginDialog.isLoginValid()) {
		setLoggedInEmployee(loginDialog.getLoggedInEmployee());
		setLoggedInAuthorisationLevel(loggedInEmployee.getAuthorisationLevel());
		bLoggedIn = (getLoggedInAuthorisationLevel() != AuthorisationLevel.DELETED);
	    }

	    loginDialog.dispose();

	    if (!bLoggedIn) {

		int n = JOptionPane.showConfirmDialog(null,
			"You have not logged in, the application will quit - are you sure?",
			"Warning",
			JOptionPane.YES_NO_OPTION,
			JOptionPane.WARNING_MESSAGE,
			null);

		if (n == JOptionPane.YES_OPTION) {
		    System.exit(0);
		}
	    }
	}
    }

    @Action(enabledProperty = "recordSelected")
    public void acknowledgeEvent() {

	entityManager.getTransaction().begin();
        
	int[] selected = masterTable.getSelectedRows();
	List<TimeRecording.tables.Event> toAcknowledge =
                new ArrayList<TimeRecording.tables.Event>(selected.length);

	for (int idx = 0; idx < selected.length; idx++) {
	    
            TimeRecording.tables.Event el = eventList.get(
                    masterTable.convertRowIndexToModel(selected[idx]));

	    // Set acknowledgement fields
	    el.setAcknowledged(true);
	    el.setAcknowledgedById(loggedInEmployee);
	    el.setAcknowledgedTime(new Date());
	}

	// Store acknowledgements
	entityManager.getTransaction().commit();

	// Now remove newly acknowledged events from the list if the button's pressed
	showAllEvents();
    }

    @Action
    @SuppressWarnings("unchecked")
    public void showAllEvents() {

        Query query;
	if (showAllButton.isSelected()) {
            query = entityManager.createNamedQuery("Event.findAll");
            
	} else {
            query = entityManager.createNamedQuery("Event.findByAcknowledged");
            query.setParameter("acknowledged", false);
	}

        eventList.clear();
        eventList.addAll(query.getResultList());

	// Scroll table to show latest record
	int row = eventList.size() - 1;
	masterTable.scrollRectToVisible(masterTable.getCellRect(row, 0, true));
    }

    /** This method is called from within the constructor to initialise the form.
     * 
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        mainPanel = new javax.swing.JPanel();
        timeRecordingToolBar = new javax.swing.JToolBar();
        logoutButton = new javax.swing.JButton();
        employeesToggle = new javax.swing.JToggleButton();
        badgesToggle = new javax.swing.JToggleButton();
        holidayRequestToggle = new javax.swing.JToggleButton();
        holidayAdjustmentToggle = new javax.swing.JToggleButton();
        sicknessReportToggle = new javax.swing.JToggleButton();
        timesheetsToggle = new javax.swing.JToggleButton();
        clockedTimesToggle = new javax.swing.JToggleButton();
        monthEndToggle = new javax.swing.JToggleButton();
        sessionsToggle = new javax.swing.JToggleButton();
        jButton1 = new javax.swing.JButton();
        eventLogPanel = new javax.swing.JPanel();
        masterScrollPane = new javax.swing.JScrollPane();
        masterTable = new javax.swing.JTable();
        buttonPanel = new javax.swing.JPanel();
        acknowledgeButton = new javax.swing.JButton();
        showAllButton = new javax.swing.JToggleButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        fileSeparator1 = new javax.swing.JSeparator();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        toolsMenu = new javax.swing.JMenu();
        toolsSeparator = new javax.swing.JSeparator();
        monthEndMenu = new javax.swing.JMenu();
        anomaliesReportMenuItem = new javax.swing.JMenuItem();
        monthEndSummaryReportMenuItem = new javax.swing.JMenuItem();
        monthEndCloseOffMenuItem = new javax.swing.JMenuItem();
        errorLoggingMenu = new javax.swing.JMenu();
        severeMenuItem = new javax.swing.JRadioButtonMenuItem();
        warningMenuItem = new javax.swing.JRadioButtonMenuItem();
        infoMenuItem = new javax.swing.JRadioButtonMenuItem();
        configMenuItem = new javax.swing.JRadioButtonMenuItem();
        fineMenuItem = new javax.swing.JRadioButtonMenuItem();
        finerMenuItem = new javax.swing.JRadioButtonMenuItem();
        finestMenuItem = new javax.swing.JRadioButtonMenuItem();
        toolsSeparator1 = new javax.swing.JPopupMenu.Separator();
        setLoggingFolderItem = new javax.swing.JMenuItem();
        refreshMenu = new javax.swing.JMenu();
        refreshAll = new javax.swing.JMenuItem();
        refreshHolidays = new javax.swing.JMenuItem();
        refreshSickness = new javax.swing.JMenuItem();
        clockedTime = new javax.swing.JMenuItem();
        allocatedHours = new javax.swing.JMenuItem();
        monthEnd = new javax.swing.JMenuItem();
        jMenuItem1 = new javax.swing.JMenuItem();
        executeAlertCheckMenuItem = new javax.swing.JMenuItem();
        reportsMenu = new javax.swing.JMenu();
        absenceReportMenu = new javax.swing.JMenu();
        weekReportMenu = new javax.swing.JMenu();
        lastWeekReportItem = new javax.swing.JMenuItem();
        thisWeekReportItem = new javax.swing.JMenuItem();
        nextWeekReportItem = new javax.swing.JMenuItem();
        chooseWeekReportItem = new javax.swing.JMenuItem();
        monthReportMenu = new javax.swing.JMenu();
        lastMonthReportItem = new javax.swing.JMenuItem();
        thisMonthReportItem = new javax.swing.JMenuItem();
        nextMonthReportItem = new javax.swing.JMenuItem();
        chooseMonthReportItem = new javax.swing.JMenuItem();
        yearReportMenu = new javax.swing.JMenu();
        thisYearReportItem = new javax.swing.JMenuItem();
        thisYearReportItem1 = new javax.swing.JMenuItem();
        thisYearReportItem2 = new javax.swing.JMenuItem();
        chooseYearReportItem = new javax.swing.JMenuItem();
        timesheetReportMenu = new javax.swing.JMenu();
        lastWeekTimesheetReport = new javax.swing.JMenuItem();
        thisWeekTimesheetReport = new javax.swing.JMenuItem();
        anyWeekTimesheetReport = new javax.swing.JMenuItem();
        collatedTimeAllReportMenu = new javax.swing.JMenu();
        lastMonthCollatedTimeAll = new javax.swing.JMenuItem();
        thisMonthCollatedTimeAll = new javax.swing.JMenuItem();
        anyMonthCollatedTimeAll = new javax.swing.JMenuItem();
        anyDatesCollatedTimeAll = new javax.swing.JMenuItem();
        collatedTimeSalariedReportMenu = new javax.swing.JMenu();
        lastMonthCollatedTimeSalaried = new javax.swing.JMenuItem();
        thisMonthCollatedTimeSalaried = new javax.swing.JMenuItem();
        anyMonthCollatedTimeSalaried = new javax.swing.JMenuItem();
        anyDatesCollatedTimeSalaried = new javax.swing.JMenuItem();
        collatedTimeSessionalReportMenu = new javax.swing.JMenu();
        lastMonthCollatedTimeSessional = new javax.swing.JMenuItem();
        thisMonthCollatedTimeSessional = new javax.swing.JMenuItem();
        anyMonthCollatedTimeSessional = new javax.swing.JMenuItem();
        anyDatesCollatedTimeSessional = new javax.swing.JMenuItem();
        employeeReportMenu = new javax.swing.JMenuItem();
        monthlySummaryReportMenu = new javax.swing.JMenu();
        lastMonthSummary = new javax.swing.JMenuItem();
        thisMonthSummary = new javax.swing.JMenuItem();
        chooseMonthSummary = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem();
        jCheckBoxMenuItem2 = new javax.swing.JCheckBoxMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        loggingLevelGroup = new javax.swing.ButtonGroup();

        mainPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 4, 0));
        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setPreferredSize(new java.awt.Dimension(900, 385));

        timeRecordingToolBar.setRollover(true);
        timeRecordingToolBar.setName("timeRecordingToolBar"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(TimeRecording.TimeRecordingApp.class).getContext().getActionMap(TimeRecordingView.class, this);
        logoutButton.setAction(actionMap.get("logout")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(TimeRecording.TimeRecordingApp.class).getContext().getResourceMap(TimeRecordingView.class);
        logoutButton.setText(resourceMap.getString("logoutButton.text")); // NOI18N
        logoutButton.setFocusable(false);
        logoutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        logoutButton.setName("logoutButton"); // NOI18N
        logoutButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(logoutButton);

        employeesToggle.setAction(actionMap.get("showEmployeesDialog")); // NOI18N
        employeesToggle.setText(resourceMap.getString("employeesToggle.text")); // NOI18N
        employeesToggle.setFocusable(false);
        employeesToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        employeesToggle.setName("employeesToggle"); // NOI18N
        employeesToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(employeesToggle);

        badgesToggle.setAction(actionMap.get("showBadgesDialog")); // NOI18N
        badgesToggle.setText(resourceMap.getString("badgesToggle.text")); // NOI18N
        badgesToggle.setFocusable(false);
        badgesToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        badgesToggle.setName("badgesToggle"); // NOI18N
        badgesToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(badgesToggle);

        holidayRequestToggle.setAction(actionMap.get("showHolidayRequestDialog")); // NOI18N
        holidayRequestToggle.setText(resourceMap.getString("holidayRequestToggle.text")); // NOI18N
        holidayRequestToggle.setFocusable(false);
        holidayRequestToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        holidayRequestToggle.setName("holidayRequestToggle"); // NOI18N
        holidayRequestToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(holidayRequestToggle);

        holidayAdjustmentToggle.setAction(actionMap.get("showHolidayAdjustmentDialog")); // NOI18N
        holidayAdjustmentToggle.setText(resourceMap.getString("holidayAdjustmentToggle.text")); // NOI18N
        holidayAdjustmentToggle.setFocusable(false);
        holidayAdjustmentToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        holidayAdjustmentToggle.setName("holidayAdjustmentToggle"); // NOI18N
        holidayAdjustmentToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(holidayAdjustmentToggle);

        sicknessReportToggle.setAction(actionMap.get("showSicknessDialog")); // NOI18N
        sicknessReportToggle.setText(resourceMap.getString("sicknessReportToggle.text")); // NOI18N
        sicknessReportToggle.setFocusable(false);
        sicknessReportToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        sicknessReportToggle.setName("sicknessReportToggle"); // NOI18N
        sicknessReportToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(sicknessReportToggle);

        timesheetsToggle.setAction(actionMap.get("showTimesheetsDialog")); // NOI18N
        timesheetsToggle.setText(resourceMap.getString("timesheetsToggle.text")); // NOI18N
        timesheetsToggle.setFocusable(false);
        timesheetsToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        timesheetsToggle.setName("timesheetsToggle"); // NOI18N
        timesheetsToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(timesheetsToggle);

        clockedTimesToggle.setAction(actionMap.get("showClockedTimesDialog")); // NOI18N
        clockedTimesToggle.setText(resourceMap.getString("clockedTimesToggle.text")); // NOI18N
        clockedTimesToggle.setFocusable(false);
        clockedTimesToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        clockedTimesToggle.setName("clockedTimesToggle"); // NOI18N
        clockedTimesToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(clockedTimesToggle);

        monthEndToggle.setAction(actionMap.get("showMonthEndDialog")); // NOI18N
        monthEndToggle.setText(resourceMap.getString("monthEndToggle.text")); // NOI18N
        monthEndToggle.setFocusable(false);
        monthEndToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        monthEndToggle.setName("monthEndToggle"); // NOI18N
        monthEndToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(monthEndToggle);

        sessionsToggle.setAction(actionMap.get("showSessionsDialog")); // NOI18N
        sessionsToggle.setText(resourceMap.getString("sessionsToggle.text")); // NOI18N
        sessionsToggle.setFocusable(false);
        sessionsToggle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        sessionsToggle.setName("sessionsToggle"); // NOI18N
        sessionsToggle.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(sessionsToggle);

        jButton1.setAction(actionMap.get("reassessAllData")); // NOI18N
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setFocusable(false);
        jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton1.setName("jButton1"); // NOI18N
        jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        timeRecordingToolBar.add(jButton1);

        eventLogPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("eventLogPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, resourceMap.getFont("eventLogPanel.border.titleFont"))); // NOI18N
        eventLogPanel.setName("eventLogPanel"); // NOI18N
        eventLogPanel.setLayout(new java.awt.GridBagLayout());

        masterScrollPane.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createEmptyBorder(1, 4, 1, 4), javax.swing.BorderFactory.createEtchedBorder()));
        masterScrollPane.setName("masterScrollPane"); // NOI18N

        masterTable.setName("masterTable"); // NOI18N

        org.jdesktop.beansbinding.ELProperty eLProperty = org.jdesktop.beansbinding.ELProperty.create("${eventList}");
        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, eLProperty, masterTable);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${eventTime}"));
        columnBinding.setColumnName("Event Time");
        columnBinding.setColumnClass(java.util.Date.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${employeeId}"));
        columnBinding.setColumnName("Employee Id");
        columnBinding.setColumnClass(TimeRecording.tables.Employee.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${eventType}"));
        columnBinding.setColumnName("Event Type");
        columnBinding.setColumnClass(TimeRecording.enums.EventType.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${acknowledged}"));
        columnBinding.setColumnName("Acknowledged");
        columnBinding.setColumnClass(Boolean.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${acknowledgedById}"));
        columnBinding.setColumnName("Acknowledged By Id");
        columnBinding.setColumnClass(TimeRecording.tables.Employee.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${acknowledgedTime}"));
        columnBinding.setColumnName("Acknowledged Time");
        columnBinding.setColumnClass(java.util.Date.class);
        jTableBinding.setSourceNullValue(new ArrayList<TimeRecording.tables.Event>());
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        masterScrollPane.setViewportView(masterTable);
        masterTable.getColumnModel().getColumn(0).setHeaderValue(resourceMap.getString("masterTable.columnModel.title6")); // NOI18N
        masterTable.getColumnModel().getColumn(1).setHeaderValue(resourceMap.getString("masterTable.columnModel.title4")); // NOI18N
        masterTable.getColumnModel().getColumn(2).setHeaderValue(resourceMap.getString("masterTable.columnModel.title4")); // NOI18N
        masterTable.getColumnModel().getColumn(3).setHeaderValue(resourceMap.getString("masterTable.columnModel.title1")); // NOI18N
        masterTable.getColumnModel().getColumn(4).setHeaderValue(resourceMap.getString("masterTable.columnModel.title5")); // NOI18N
        masterTable.getColumnModel().getColumn(5).setHeaderValue(resourceMap.getString("masterTable.columnModel.title2")); // NOI18N

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        eventLogPanel.add(masterScrollPane, gridBagConstraints);

        buttonPanel.setName("buttonPanel"); // NOI18N

        acknowledgeButton.setAction(actionMap.get("acknowledgeEvent")); // NOI18N
        acknowledgeButton.setText(resourceMap.getString("acknowledgeButton.text")); // NOI18N
        acknowledgeButton.setName("acknowledgeButton"); // NOI18N
        buttonPanel.add(acknowledgeButton);

        showAllButton.setAction(actionMap.get("ShowAllEvents")); // NOI18N
        showAllButton.setText(resourceMap.getString("showAllButton.text")); // NOI18N
        showAllButton.setName("showAllButton"); // NOI18N
        buttonPanel.add(showAllButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        eventLogPanel.add(buttonPanel, gridBagConstraints);

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(timeRecordingToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 1163, Short.MAX_VALUE)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addComponent(eventLogPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1143, Short.MAX_VALUE)
                .addGap(10, 10, 10))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addComponent(timeRecordingToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(eventLogPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 372, Short.MAX_VALUE))
        );

        menuBar.setName("menuBar"); // NOI18N
        menuBar.setPreferredSize(new java.awt.Dimension(900, 21));

        fileMenu.setAction(actionMap.get("showAbsencesDialog")); // NOI18N
        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        fileSeparator1.setName("fileSeparator1"); // NOI18N
        fileMenu.add(fileSeparator1);

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        toolsMenu.setText(resourceMap.getString("Tools.text")); // NOI18N
        toolsMenu.add(toolsSeparator);

        monthEndMenu.setText(resourceMap.getString("monthEndMenu.text")); // NOI18N

        anomaliesReportMenuItem.setAction(actionMap.get("monthEnd")); // NOI18N
        anomaliesReportMenuItem.setText(resourceMap.getString("anomaliesReportMenuItem.text")); // NOI18N
        anomaliesReportMenuItem.setName("anomaliesReportMenuItem"); // NOI18N
        monthEndMenu.add(anomaliesReportMenuItem);

        monthEndSummaryReportMenuItem.setAction(actionMap.get("monthEndSummary")); // NOI18N
        monthEndSummaryReportMenuItem.setText(resourceMap.getString("monthEndSummaryReportMenuItem.text")); // NOI18N
        monthEndSummaryReportMenuItem.setName("monthEndSummaryReportMenuItem"); // NOI18N
        monthEndMenu.add(monthEndSummaryReportMenuItem);

        monthEndCloseOffMenuItem.setAction(actionMap.get("monthEndCloseOff")); // NOI18N
        monthEndCloseOffMenuItem.setText(resourceMap.getString("monthEndCloseOffMenuItem.text")); // NOI18N
        monthEndCloseOffMenuItem.setName("monthEndCloseOffMenuItem"); // NOI18N
        monthEndMenu.add(monthEndCloseOffMenuItem);

        toolsMenu.add(monthEndMenu);

        errorLoggingMenu.setText(resourceMap.getString("errorLoggingMenu.text")); // NOI18N

        severeMenuItem.setAction(actionMap.get("changeLoggingLevelSevere")); // NOI18N
        loggingLevelGroup.add(severeMenuItem);
        severeMenuItem.setText(resourceMap.getString("severeMenuItem.text")); // NOI18N
        severeMenuItem.setName("severeMenuItem"); // NOI18N
        errorLoggingMenu.add(severeMenuItem);

        warningMenuItem.setAction(actionMap.get("changeLoggingLevelWarning")); // NOI18N
        loggingLevelGroup.add(warningMenuItem);
        warningMenuItem.setText(resourceMap.getString("warningMenuItem.text")); // NOI18N
        warningMenuItem.setName("warningMenuItem"); // NOI18N
        errorLoggingMenu.add(warningMenuItem);

        infoMenuItem.setAction(actionMap.get("changeLoggingLevelInfo")); // NOI18N
        loggingLevelGroup.add(infoMenuItem);
        infoMenuItem.setText(resourceMap.getString("infoMenuItem.text")); // NOI18N
        infoMenuItem.setName("infoMenuItem"); // NOI18N
        errorLoggingMenu.add(infoMenuItem);

        configMenuItem.setAction(actionMap.get("changeLoggingLevelConfig")); // NOI18N
        loggingLevelGroup.add(configMenuItem);
        configMenuItem.setText(resourceMap.getString("configMenuItem.text")); // NOI18N
        configMenuItem.setName("configMenuItem"); // NOI18N
        errorLoggingMenu.add(configMenuItem);

        fineMenuItem.setAction(actionMap.get("changeLoggingLevelFine")); // NOI18N
        loggingLevelGroup.add(fineMenuItem);
        fineMenuItem.setText(resourceMap.getString("fineMenuItem.text")); // NOI18N
        fineMenuItem.setName("fineMenuItem"); // NOI18N
        errorLoggingMenu.add(fineMenuItem);

        finerMenuItem.setAction(actionMap.get("changeLoggingLevelFiner")); // NOI18N
        loggingLevelGroup.add(finerMenuItem);
        finerMenuItem.setText(resourceMap.getString("finerMenuItem.text")); // NOI18N
        finerMenuItem.setName("finerMenuItem"); // NOI18N
        errorLoggingMenu.add(finerMenuItem);

        finestMenuItem.setAction(actionMap.get("changeLoggingLevelFinest")); // NOI18N
        loggingLevelGroup.add(finestMenuItem);
        finestMenuItem.setSelected(true);
        finestMenuItem.setText(resourceMap.getString("finestMenuItem.text")); // NOI18N
        finestMenuItem.setName("finestMenuItem"); // NOI18N
        errorLoggingMenu.add(finestMenuItem);
        errorLoggingMenu.add(toolsSeparator1);

        setLoggingFolderItem.setAction(actionMap.get("changeLoggingFolder")); // NOI18N
        setLoggingFolderItem.setText(resourceMap.getString("setLoggingFolderItem.text")); // NOI18N
        setLoggingFolderItem.setName("setLoggingFolderItem"); // NOI18N
        errorLoggingMenu.add(setLoggingFolderItem);

        toolsMenu.add(errorLoggingMenu);

        refreshMenu.setText(resourceMap.getString("refreshMenu.text")); // NOI18N
        refreshMenu.setName("refreshMenu"); // NOI18N

        refreshAll.setAction(actionMap.get("reassessAllData")); // NOI18N
        refreshAll.setText(resourceMap.getString("refreshAll.text")); // NOI18N
        refreshAll.setName("refreshAll"); // NOI18N
        refreshMenu.add(refreshAll);

        refreshHolidays.setAction(actionMap.get("reassessHolidays")); // NOI18N
        refreshHolidays.setText(resourceMap.getString("refreshHolidays.text")); // NOI18N
        refreshHolidays.setName("refreshHolidays"); // NOI18N
        refreshMenu.add(refreshHolidays);

        refreshSickness.setAction(actionMap.get("reassessSickness")); // NOI18N
        refreshSickness.setText(resourceMap.getString("refreshSickness.text")); // NOI18N
        refreshSickness.setName("refreshSickness"); // NOI18N
        refreshMenu.add(refreshSickness);

        clockedTime.setAction(actionMap.get("reassessClockedTime")); // NOI18N
        clockedTime.setText(resourceMap.getString("clockedTime.text")); // NOI18N
        clockedTime.setName("clockedTime"); // NOI18N
        refreshMenu.add(clockedTime);

        allocatedHours.setAction(actionMap.get("reassessAllocatedTime")); // NOI18N
        allocatedHours.setText(resourceMap.getString("allocatedHours.text")); // NOI18N
        allocatedHours.setName("allocatedHours"); // NOI18N
        refreshMenu.add(allocatedHours);

        monthEnd.setAction(actionMap.get("reassesMonthEnd")); // NOI18N
        monthEnd.setText(resourceMap.getString("monthEnd.text")); // NOI18N
        monthEnd.setName("monthEnd"); // NOI18N
        refreshMenu.add(monthEnd);

        toolsMenu.add(refreshMenu);

        jMenuItem1.setAction(actionMap.get("showPublicHolidayDialog")); // NOI18N
        jMenuItem1.setText(resourceMap.getString("jMenuItem1.text")); // NOI18N
        jMenuItem1.setName("jMenuItem1"); // NOI18N
        toolsMenu.add(jMenuItem1);

        executeAlertCheckMenuItem.setText(resourceMap.getString("executeAlertCheckMenuItem.text")); // NOI18N
        executeAlertCheckMenuItem.setName("executeAlertCheckMenuItem"); // NOI18N
        toolsMenu.add(executeAlertCheckMenuItem);

        menuBar.add(toolsMenu);

        reportsMenu.setText(resourceMap.getString("reportsMenu.text")); // NOI18N

        absenceReportMenu.setText(resourceMap.getString("absenceReportMenu.text")); // NOI18N

        weekReportMenu.setText(resourceMap.getString("weekReportMenu.text")); // NOI18N

        lastWeekReportItem.setAction(actionMap.get("lastWeekAbsenceReport")); // NOI18N
        lastWeekReportItem.setText(resourceMap.getString("lastWeekReportItem.text")); // NOI18N
        lastWeekReportItem.setName("lastWeekReportItem"); // NOI18N
        weekReportMenu.add(lastWeekReportItem);

        thisWeekReportItem.setAction(actionMap.get("thisWeekAbsenceReport")); // NOI18N
        thisWeekReportItem.setText(resourceMap.getString("thisWeekReportItem.text")); // NOI18N
        thisWeekReportItem.setName("thisWeekReportItem"); // NOI18N
        weekReportMenu.add(thisWeekReportItem);

        nextWeekReportItem.setAction(actionMap.get("nextWeekAbsenceReport")); // NOI18N
        nextWeekReportItem.setText(resourceMap.getString("nextWeekReportItem.text")); // NOI18N
        nextWeekReportItem.setName("nextWeekReportItem"); // NOI18N
        weekReportMenu.add(nextWeekReportItem);

        chooseWeekReportItem.setAction(actionMap.get("chooseWeekAbsenceReport")); // NOI18N
        chooseWeekReportItem.setText(resourceMap.getString("chooseWeekReportItem.text")); // NOI18N
        chooseWeekReportItem.setName("chooseWeekReportItem"); // NOI18N
        weekReportMenu.add(chooseWeekReportItem);

        absenceReportMenu.add(weekReportMenu);

        monthReportMenu.setText(resourceMap.getString("monthReportMenu.text")); // NOI18N
        monthReportMenu.setName("monthReportMenu"); // NOI18N

        lastMonthReportItem.setAction(actionMap.get("lastMonthAbsenceReport")); // NOI18N
        lastMonthReportItem.setText(resourceMap.getString("lastMonthReportItem.text")); // NOI18N
        lastMonthReportItem.setName("lastMonthReportItem"); // NOI18N
        monthReportMenu.add(lastMonthReportItem);

        thisMonthReportItem.setAction(actionMap.get("thisMonthAbsenceReport")); // NOI18N
        thisMonthReportItem.setText(resourceMap.getString("thisMonthReportItem.text")); // NOI18N
        thisMonthReportItem.setName("thisMonthReportItem"); // NOI18N
        monthReportMenu.add(thisMonthReportItem);

        nextMonthReportItem.setAction(actionMap.get("nextMonthAbsenceReport")); // NOI18N
        nextMonthReportItem.setText(resourceMap.getString("nextMonthReportItem.text")); // NOI18N
        nextMonthReportItem.setName("nextMonthReportItem"); // NOI18N
        monthReportMenu.add(nextMonthReportItem);

        chooseMonthReportItem.setAction(actionMap.get("chooseMonthlyAbsenceReport")); // NOI18N
        chooseMonthReportItem.setText(resourceMap.getString("chooseMonthReportItem.text")); // NOI18N
        chooseMonthReportItem.setName("chooseMonthReportItem"); // NOI18N
        monthReportMenu.add(chooseMonthReportItem);

        absenceReportMenu.add(monthReportMenu);

        yearReportMenu.setText(resourceMap.getString("yearReportMenu.text")); // NOI18N

        thisYearReportItem.setAction(actionMap.get("lastYearAbsenceReport")); // NOI18N
        thisYearReportItem.setText(resourceMap.getString("thisYearReportItem.text")); // NOI18N
        thisYearReportItem.setName("thisYearReportItem"); // NOI18N
        yearReportMenu.add(thisYearReportItem);

        thisYearReportItem1.setAction(actionMap.get("thisYearAbsenceReport")); // NOI18N
        thisYearReportItem1.setText(resourceMap.getString("thisYearReportItem1.text")); // NOI18N
        thisYearReportItem1.setName("thisYearReportItem1"); // NOI18N
        yearReportMenu.add(thisYearReportItem1);

        thisYearReportItem2.setAction(actionMap.get("nextYearAbsenceReport")); // NOI18N
        thisYearReportItem2.setText(resourceMap.getString("thisYearReportItem2.text")); // NOI18N
        thisYearReportItem2.setName("thisYearReportItem2"); // NOI18N
        yearReportMenu.add(thisYearReportItem2);

        chooseYearReportItem.setAction(actionMap.get("choosetYearAbsenceReport")); // NOI18N
        chooseYearReportItem.setText(resourceMap.getString("chooseYearReportItem.text")); // NOI18N
        chooseYearReportItem.setName("chooseYearReportItem"); // NOI18N
        yearReportMenu.add(chooseYearReportItem);

        absenceReportMenu.add(yearReportMenu);

        reportsMenu.add(absenceReportMenu);

        timesheetReportMenu.setText(resourceMap.getString("timesheetReportMenu.text")); // NOI18N
        timesheetReportMenu.setName("timesheetReportMenu"); // NOI18N

        lastWeekTimesheetReport.setAction(actionMap.get("lastWeekTimesheetReport")); // NOI18N
        lastWeekTimesheetReport.setText(resourceMap.getString("lastWeekTimesheetReport.text")); // NOI18N
        lastWeekTimesheetReport.setName("lastWeekTimesheetReport"); // NOI18N
        timesheetReportMenu.add(lastWeekTimesheetReport);

        thisWeekTimesheetReport.setAction(actionMap.get("thisWeekTimesheetReport")); // NOI18N
        thisWeekTimesheetReport.setText(resourceMap.getString("thisWeekTimesheetReport.text")); // NOI18N
        thisWeekTimesheetReport.setName("thisWeekTimesheetReport"); // NOI18N
        timesheetReportMenu.add(thisWeekTimesheetReport);

        anyWeekTimesheetReport.setAction(actionMap.get("anyWeekTimesheetReport")); // NOI18N
        anyWeekTimesheetReport.setText(resourceMap.getString("anyWeekTimesheetReport.text")); // NOI18N
        anyWeekTimesheetReport.setName("anyWeekTimesheetReport"); // NOI18N
        timesheetReportMenu.add(anyWeekTimesheetReport);

        reportsMenu.add(timesheetReportMenu);

        collatedTimeAllReportMenu.setText(resourceMap.getString("collatedTimeAllReportMenu.text")); // NOI18N

        lastMonthCollatedTimeAll.setAction(actionMap.get("lastMonthCollatedTimeAll")); // NOI18N
        lastMonthCollatedTimeAll.setText(resourceMap.getString("lastMonthCollatedTimeAll.text")); // NOI18N
        lastMonthCollatedTimeAll.setName("lastMonthCollatedTimeAll"); // NOI18N
        collatedTimeAllReportMenu.add(lastMonthCollatedTimeAll);

        thisMonthCollatedTimeAll.setAction(actionMap.get("thisMonthCollatedTimeAll")); // NOI18N
        thisMonthCollatedTimeAll.setText(resourceMap.getString("thisMonthCollatedTimeAll.text")); // NOI18N
        thisMonthCollatedTimeAll.setName("thisMonthCollatedTimeAll"); // NOI18N
        collatedTimeAllReportMenu.add(thisMonthCollatedTimeAll);

        anyMonthCollatedTimeAll.setAction(actionMap.get("anyMonthCollatedTimeAll")); // NOI18N
        anyMonthCollatedTimeAll.setText(resourceMap.getString("anyMonthCollatedTimeAll.text")); // NOI18N
        anyMonthCollatedTimeAll.setName("anyMonthCollatedTimeAll"); // NOI18N
        collatedTimeAllReportMenu.add(anyMonthCollatedTimeAll);

        anyDatesCollatedTimeAll.setAction(actionMap.get("anyDatesCollatedTimeAll")); // NOI18N
        anyDatesCollatedTimeAll.setText(resourceMap.getString("anyDatesCollatedTimeAll.text")); // NOI18N
        anyDatesCollatedTimeAll.setName("anyDatesCollatedTimeAll"); // NOI18N
        collatedTimeAllReportMenu.add(anyDatesCollatedTimeAll);

        reportsMenu.add(collatedTimeAllReportMenu);

        collatedTimeSalariedReportMenu.setText(resourceMap.getString("collatedTimeSalariedReportMenu.text")); // NOI18N
        collatedTimeSalariedReportMenu.setName("collatedTimeSalariedReportMenu"); // NOI18N

        lastMonthCollatedTimeSalaried.setAction(actionMap.get("lastMonthCollatedTimeSalaried")); // NOI18N
        lastMonthCollatedTimeSalaried.setText(resourceMap.getString("lastMonthCollatedTimeSalaried.text")); // NOI18N
        lastMonthCollatedTimeSalaried.setName("lastMonthCollatedTimeSalaried"); // NOI18N
        collatedTimeSalariedReportMenu.add(lastMonthCollatedTimeSalaried);

        thisMonthCollatedTimeSalaried.setAction(actionMap.get("thisMonthCollatedTimeSalaried")); // NOI18N
        thisMonthCollatedTimeSalaried.setText(resourceMap.getString("thisMonthCollatedTimeSalaried.text")); // NOI18N
        thisMonthCollatedTimeSalaried.setName("thisMonthCollatedTimeSalaried"); // NOI18N
        collatedTimeSalariedReportMenu.add(thisMonthCollatedTimeSalaried);

        anyMonthCollatedTimeSalaried.setAction(actionMap.get("anyMonthCollatedTimeSalaried")); // NOI18N
        anyMonthCollatedTimeSalaried.setText(resourceMap.getString("anyMonthCollatedTimeSalaried.text")); // NOI18N
        anyMonthCollatedTimeSalaried.setName("anyMonthCollatedTimeSalaried"); // NOI18N
        collatedTimeSalariedReportMenu.add(anyMonthCollatedTimeSalaried);

        anyDatesCollatedTimeSalaried.setAction(actionMap.get("anyDatesCollatedTimeSalaried")); // NOI18N
        anyDatesCollatedTimeSalaried.setText(resourceMap.getString("anyDatesCollatedTimeSalaried.text")); // NOI18N
        anyDatesCollatedTimeSalaried.setName("anyDatesCollatedTimeSalaried"); // NOI18N
        collatedTimeSalariedReportMenu.add(anyDatesCollatedTimeSalaried);

        reportsMenu.add(collatedTimeSalariedReportMenu);

        collatedTimeSessionalReportMenu.setText(resourceMap.getString("collatedTimeSessionalReportMenu.text")); // NOI18N

        lastMonthCollatedTimeSessional.setAction(actionMap.get("lastMonthCollatedTimeSessional")); // NOI18N
        lastMonthCollatedTimeSessional.setText(resourceMap.getString("lastMonthCollatedTimeSessional.text")); // NOI18N
        lastMonthCollatedTimeSessional.setName("lastMonthCollatedTimeSessional"); // NOI18N
        collatedTimeSessionalReportMenu.add(lastMonthCollatedTimeSessional);

        thisMonthCollatedTimeSessional.setAction(actionMap.get("thisMonthCollatedTimeSessional")); // NOI18N
        thisMonthCollatedTimeSessional.setText(resourceMap.getString("thisMonthCollatedTimeSessional.text")); // NOI18N
        thisMonthCollatedTimeSessional.setName("thisMonthCollatedTimeSessional"); // NOI18N
        collatedTimeSessionalReportMenu.add(thisMonthCollatedTimeSessional);

        anyMonthCollatedTimeSessional.setAction(actionMap.get("anyMonthCollatedTimeSessional")); // NOI18N
        anyMonthCollatedTimeSessional.setText(resourceMap.getString("anyMonthCollatedTimeSessional.text")); // NOI18N
        anyMonthCollatedTimeSessional.setName("anyMonthCollatedTimeSessional"); // NOI18N
        collatedTimeSessionalReportMenu.add(anyMonthCollatedTimeSessional);

        anyDatesCollatedTimeSessional.setAction(actionMap.get("anyDatesCollatedTimeSessional")); // NOI18N
        anyDatesCollatedTimeSessional.setText(resourceMap.getString("anyDatesCollatedTimeSessional.text")); // NOI18N
        anyDatesCollatedTimeSessional.setName("anyDatesCollatedTimeSessional"); // NOI18N
        collatedTimeSessionalReportMenu.add(anyDatesCollatedTimeSessional);

        reportsMenu.add(collatedTimeSessionalReportMenu);

        employeeReportMenu.setAction(actionMap.get("employeeSummaryReport")); // NOI18N
        employeeReportMenu.setText(resourceMap.getString("employeeReportMenu.text")); // NOI18N
        employeeReportMenu.setName("employeeReportMenu"); // NOI18N
        reportsMenu.add(employeeReportMenu);

        monthlySummaryReportMenu.setText(resourceMap.getString("monthlySummaryReportMenu.text")); // NOI18N
        monthlySummaryReportMenu.setName("monthlySummaryReportMenu"); // NOI18N

        lastMonthSummary.setAction(actionMap.get("lastMonthSummaryTime")); // NOI18N
        lastMonthSummary.setText(resourceMap.getString("lastMonthSummary.text")); // NOI18N
        lastMonthSummary.setName("lastMonthSummary"); // NOI18N
        monthlySummaryReportMenu.add(lastMonthSummary);

        thisMonthSummary.setText(resourceMap.getString("thisMonthSummary.text")); // NOI18N
        thisMonthSummary.setName("thisMonthSummary"); // NOI18N
        monthlySummaryReportMenu.add(thisMonthSummary);

        chooseMonthSummary.setAction(actionMap.get("anyMonthSummaryTime")); // NOI18N
        chooseMonthSummary.setText(resourceMap.getString("chooseMonthSummary.text")); // NOI18N
        chooseMonthSummary.setName("chooseMonthSummary"); // NOI18N
        monthlySummaryReportMenu.add(chooseMonthSummary);

        reportsMenu.add(monthlySummaryReportMenu);

        jMenu1.setText(resourceMap.getString("jMenu1.text")); // NOI18N

        jCheckBoxMenuItem1.setText(resourceMap.getString("jCheckBoxMenuItem1.text")); // NOI18N
        jCheckBoxMenuItem1.setName("jCheckBoxMenuItem1"); // NOI18N

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${printWatermark}"), jCheckBoxMenuItem1, org.jdesktop.beansbinding.BeanProperty.create("selected"));
        bindingGroup.addBinding(binding);

        jMenu1.add(jCheckBoxMenuItem1);

        jCheckBoxMenuItem2.setText(resourceMap.getString("jCheckBoxMenuItem2.text")); // NOI18N
        jCheckBoxMenuItem2.setName("jCheckBoxMenuItem2"); // NOI18N

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${printGreenShading}"), jCheckBoxMenuItem2, org.jdesktop.beansbinding.BeanProperty.create("selected"));
        bindingGroup.addBinding(binding);

        jMenu1.add(jCheckBoxMenuItem2);

        reportsMenu.add(jMenu1);

        menuBar.add(reportsMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N
        statusPanel.setPreferredSize(new java.awt.Dimension(900, 27));

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 993, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 1163, Short.MAX_VALUE)
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
                .addGap(2, 2, 2)
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
        setToolBar(timeRecordingToolBar);

        bindingGroup.bind();
    }// </editor-fold>//GEN-END:initComponents

    @Action
    public void monthEnd() {
        GregorianCalendar cal = new GregorianCalendar();
        new AnomaliesReport().viewReport(entityManager, DaisyChainUtilities.firstDayOfMonth(cal).getTime(), DaisyChainUtilities.lastDayOfMonth(cal).getTime());
    }

    @Action(enabledProperty = "supervisorLoggedIn")
    public void monthEndCloseOff() {
        new MonthEndProcessingDialog(this.getFrame(), entityManager).setVisible(true);
    }

    @Action
    public void monthEndSummary() {
        new EndOfMonthSummary().viewReport(entityManager);
    }

    // <editor-fold defaultstate="collapsed" desc="Weekly Absence Reporting">
    @Action
    public void lastWeekAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.DATE, -7);
        absenceReportForWeek(cal);
    }

    @Action
    public void thisWeekAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        absenceReportForWeek(cal);
    }

    @Action
    public void nextWeekAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.DATE, 7);
        absenceReportForWeek(cal);
    }

    @Action
    public void chooseWeekAbsenceReport() {
        
        SelectDateDialog dateDialog = new SelectDateDialog(
                this.getFrame(), SelectDateDialog.DateType.WEEK);
        dateDialog.setVisible(true);
        if (dateDialog.getSelectedCalendar() == null) {
            return;
        }
        absenceReportForWeek(dateDialog.getSelectedCalendar());
    }

    private void absenceReportForWeek(GregorianCalendar cal) {

        Cursor savedCursor = getFrame().getCursor();
        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            new CalendarReport().singleWeekAbsenceReport(new DateRange(
                    DaisyChainUtilities.firstDayOfWeek(cal).getTime(),
                    DaisyChainUtilities.lastDayOfWeek(cal).getTime()),
                    new AbsenceIconProvider(), entityManager);

        } finally {
            getFrame().setCursor(savedCursor);
        }
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Monthly Absence Reporting">
    @Action
    public void lastMonthAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.MONTH, -1);
        absenceReportForMonth(cal);
    }

    @Action
    public void thisMonthAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        absenceReportForMonth(cal);
    }

    @Action
    public void nextMonthAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.MONTH, 1);
        absenceReportForMonth(cal);
    }

    @Action
    public void chooseMonthlyAbsenceReport() {
        SelectDateDialog dateDialog = new SelectDateDialog(
                this.getFrame(), SelectDateDialog.DateType.MONTH);
        dateDialog.setVisible(true);
        if (dateDialog.getSelectedCalendar() == null) {
            return;
        }
        absenceReportForMonth(dateDialog.getSelectedCalendar());
    }

    public void absenceReportForMonth(GregorianCalendar cal) {

        Cursor savedCursor = getFrame().getCursor();
        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            new CalendarReport().singleMonthAbsenceReport(new DateRange(
                    DaisyChainUtilities.firstDayOfMonth(cal).getTime(),
                    DaisyChainUtilities.lastDayOfMonth(cal).getTime()),
                    new AbsenceIconProvider(), entityManager);

        } finally {
            getFrame().setCursor(savedCursor);
        }
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Annual Absence Reporting">
    @Action
    public void lastYearAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.YEAR, -1);
        absenceReportForYear(cal);
    }

    @Action
    public void thisYearAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        absenceReportForYear(cal);
    }

    @Action
    public void nextYearAbsenceReport() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.YEAR, 1);
        absenceReportForYear(cal);
    }

    @Action
    public void choosetYearAbsenceReport() {
        SelectDateDialog dateDialog = new SelectDateDialog(
                this.getFrame(), SelectDateDialog.DateType.YEAR);
        dateDialog.setVisible(true);
        if (dateDialog.getSelectedCalendar() == null) {
            return;
        }
        absenceReportForYear(dateDialog.getSelectedCalendar());
    }

    @Action
    public void absenceReportForYear(GregorianCalendar cal) {

        ArrayList<Employee> selectedEmployees = getEmployeesForReport();
        if (selectedEmployees.isEmpty()) {
            return;
        }

        Cursor savedCursor = getFrame().getCursor();

        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

            new CalendarReport().singleYearAbsenceReport(new DateRange(
                    DaisyChainUtilities.firstDayOfSystemYear(cal).getTime(),
                    DaisyChainUtilities.lastDayOfSystemYear(cal).getTime()),
                    new AbsenceIconProvider(), selectedEmployees);

        } finally {
            getFrame().setCursor(savedCursor);
        }
    } // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Timesheet Reporting">

    @Action
    private void lastMonthCollatedTime(boolean sessional, boolean salaried) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.MONTH, -1);
        timesheetReport(
                DaisyChainUtilities.firstDayOfMonth(cal),
                DaisyChainUtilities.lastDayOfMonth(cal),
                sessional, salaried);
    }

    @Action
    private void thisMonthCollatedTime(boolean sessional, boolean salaried) {
        GregorianCalendar cal = new GregorianCalendar();
        timesheetReport(
                DaisyChainUtilities.firstDayOfMonth(cal),
                DaisyChainUtilities.lastDayOfMonth(cal),
                sessional, salaried);
    }

    @Action
    private void anyMonthCollatedTime(boolean sessional, boolean salaried) {
        SelectDateDialog dateDialog = new SelectDateDialog(
                this.getFrame(), SelectDateDialog.DateType.MONTH);
        dateDialog.setVisible(true);
        if (dateDialog.getSelectedCalendar() == null) {
            return;
        }
        GregorianCalendar cal = dateDialog.getSelectedCalendar();
        timesheetReport(
                DaisyChainUtilities.firstDayOfMonth(cal),
                DaisyChainUtilities.lastDayOfMonth(cal),
                sessional, salaried);
    }

    @Action
    private void anyDatesCollatedTime(boolean sessional, boolean salaried) {

        SelectDateRangeDialog dateRangeDialog = new SelectDateRangeDialog(
                this.getFrame(), Control.getActiveWindow(entityManager));

        dateRangeDialog.setVisible(true);

        if (dateRangeDialog.ok()) {
            timesheetReport(
                    dateRangeDialog.getStartCal(), dateRangeDialog.getEndCal(),
                    sessional, salaried);
        }
    }

    @Action
    public void lastMonthCollatedTimeAll() {
        lastMonthCollatedTime(true, true);
    }

    @Action
    public void thisMonthCollatedTimeAll() {
        thisMonthCollatedTime(true, true);
    }

    @Action
    public void anyMonthCollatedTimeAll() {
        anyMonthCollatedTime(true, true);
    }

    @Action
    public void anyDatesCollatedTimeAll() {
        anyDatesCollatedTime(true, true);
    }

    @Action
    public void lastMonthCollatedTimeSalaried() {
        lastMonthCollatedTime(false, true);
    }

    @Action
    public void thisMonthCollatedTimeSalaried() {
        thisMonthCollatedTime(false, true);
    }

    @Action
    public void anyMonthCollatedTimeSalaried() {
        anyMonthCollatedTime(false, true);
    }

    @Action
    public void anyDatesCollatedTimeSalaried() {
        anyDatesCollatedTime(false, true);
    }

    @Action
    public void lastMonthCollatedTimeSessional() {
        lastMonthCollatedTime(true, false);
    }

    @Action
    public void thisMonthCollatedTimeSessional() {
        thisMonthCollatedTime(true, false);
    }

    @Action
    public void anyMonthCollatedTimeSessional() {
        anyMonthCollatedTime(true, false);
    }

    @Action
    public void anyDatesCollatedTimeSessional() {
        anyDatesCollatedTime(true, false);
    }

    private void timesheetReport(
            GregorianCalendar startDate, GregorianCalendar endDate,
            boolean sessional, boolean salaried) {

        ArrayList<Employee> selectedEmployees = getEmployeesForReport();
        if (selectedEmployees.isEmpty()) {
            return;
        }

        Cursor savedCursor = getFrame().getCursor();
        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            new CollationReport().periodReport(
                    new DateRange(startDate.getTime(), endDate.getTime()),
                    selectedEmployees, entityManager,
                    sessional, salaried);
        } finally {
            getFrame().setCursor(savedCursor);
        }
        
    }// </editor-fold>

    @Action
    public void employeeSummaryReport() {

        ArrayList<Employee> selectedEmployees = getEmployeesForReport();
        if (selectedEmployees.isEmpty()) {
            return;
        }

        Cursor savedCursor = getFrame().getCursor();

        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

            new EmployeeSummaryReport().viewReport(selectedEmployees,
                    DaisyChainUtilities.getThisYear());

        } finally {
            getFrame().setCursor(savedCursor);
        }
    }

    private ArrayList<Employee> getEmployeesForReport() {

        SelectEmployeesDialog selectEmployees =
                new SelectEmployeesDialog(this.getFrame(), entityManager, true);

        selectEmployees.setVisible(true);
        return selectEmployees.getSelectedEmployees();
    }

    // <editor-fold defaultstate="collapsed" desc="Monthly Summary Reporting">

    @Action
    public void lastMonthSummaryTime() {
        GregorianCalendar cal = new GregorianCalendar();
        cal.add(GregorianCalendar.MONTH, -1);
        monthlySummaryReport(DaisyChainUtilities.firstDayOfMonth(cal));
    }

    @Action
    public void thisMonthSummaryTime() {
        GregorianCalendar cal = new GregorianCalendar();
        monthlySummaryReport(DaisyChainUtilities.firstDayOfMonth(cal));
    }

    @Action
    public void anyMonthSummaryTime() {
        SelectDateDialog dateDialog = new SelectDateDialog(
                this.getFrame(), SelectDateDialog.DateType.MONTH);
        dateDialog.setVisible(true);
        if (dateDialog.getSelectedCalendar() == null) {
            return;
        }
        GregorianCalendar cal = dateDialog.getSelectedCalendar();
        monthlySummaryReport(DaisyChainUtilities.firstDayOfMonth(cal));
    }

    private void monthlySummaryReport(GregorianCalendar startDate) {

        ArrayList<Employee> selectedEmployees = getEmployeesForReport();
        if (selectedEmployees.isEmpty()) {
            return;
        }

        Cursor savedCursor = getFrame().getCursor();
        try {
            getFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            new MonthEndSummaryReport().viewReport(
                    selectedEmployees, entityManager, startDate.getTime());
        } finally {
            getFrame().setCursor(savedCursor);
        }

    }// </editor-fold>

    @Action
    public void changeLoggingLevelSevere() {
        setLoggingLevel(Level.SEVERE);
    }

    @Action
    public void changeLoggingLevelWarning() {
        setLoggingLevel(Level.WARNING);
    }

    @Action
    public void changeLoggingLevelInfo() {
        setLoggingLevel(Level.INFO);
    }

    @Action
    public void changeLoggingLevelConfig() {
        setLoggingLevel(Level.CONFIG);
    }

    @Action
    public void changeLoggingLevelFine() {
        setLoggingLevel(Level.FINE);
    }

    @Action
    public void changeLoggingLevelFiner() {
        setLoggingLevel(Level.FINER);
    }

    @Action
    public void changeLoggingLevelFinest() {
        setLoggingLevel(Level.FINEST);
    }

    @Action
    public void changeLoggingFolder() {

        JFileChooser folderDialog;
        if (loggingFolder.equals("%h")) {
            folderDialog = new JFileChooser();
        } else {
            folderDialog = new JFileChooser(loggingFolder);
        }

        folderDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int option = folderDialog.showOpenDialog(this.getFrame());

        if (option == JFileChooser.APPROVE_OPTION) {
            setLoggingFolder(folderDialog.getSelectedFile().getAbsolutePath());
        }
    }

    private void setLoggingLevel(Level level) {
        
        BASE_LOGGER.setLevel(level);
        loggingLevel = level;

        if (loggingLevel.equals(Level.SEVERE)) {
            severeMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.WARNING)) {
            warningMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.INFO)) {
            infoMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.CONFIG)) {
            configMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.FINE)) {
            fineMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.FINER)) {
            finerMenuItem.setSelected(true);
        } else if (loggingLevel.equals(Level.FINEST)) {
            finestMenuItem.setSelected(true);
        }

        props.setProperty("logging.level", loggingLevel.toString());
        saveProperties();
    }

    private void setLoggingFolder(String folder) {

        // Remove any existing file handler

        if (FILE_HANDLER != null) {
            BASE_LOGGER.removeHandler(FILE_HANDLER);
        }

        // Create a new file handler and add it to the base logger

        try {
            FILE_HANDLER = new FileHandler(
                    folder + "/Java-%u-%g.log",
                    LOG_FILE_SIZE, LOG_FILE_COUNT);
            FILE_HANDLER.setFormatter(new SimpleFormatter());
            
            BASE_LOGGER.addHandler(FILE_HANDLER);

            loggingFolder = folder;
            props.setProperty("logging.folder", loggingFolder);
            saveProperties();

        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "Failed to configure logging", ex);
            ErrorDialog.showError(this.getFrame(), ex);
        }
    }

    private void loadProperties() {

        props = new Properties();
        loggingFolder = "%h";
        loggingLevel = Level.SEVERE;

        try {
            props.load(new FileInputStream(PROPERTIES_FILE));

            loggingFolder = props.getProperty(
                    "logging.folder", "%h");
            loggingLevel = Level.parse(props.getProperty(
                    "logging.level", Level.SEVERE.toString()));

            setPrintWatermark(Boolean.parseBoolean(props.getProperty(
                    "reporting.printWatermark", "true")));

            setPrintGreenShading(Boolean.parseBoolean(props.getProperty(
                    "reporting.printGreenShading", "true")));

        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "Error loading properties", ex);
        }
    }

    private void saveProperties() {

        try {
            props.store(new FileWriter(PROPERTIES_FILE), "TimeRecording properties");

        } catch (IOException ex) {
            LOGGER.log(Level.SEVERE, "Error saving properties", ex);
        }
    }

    @Action
    public void setReportingPreferences() {
    }

    private void performHousekeeping(DateRange range, HousekeepingTask... tasks) {

        LOGGER.info("Housekeeping Started");

        Cursor savedCursor = getFrame().getCursor();

        try {
            getFrame().setCursor(new Cursor(Cursor.WAIT_CURSOR));

            entityManager.getTransaction().begin();

            HolidayCalculations holidayCalcs = new HolidayCalculations();
            SicknessCalculations sicknessCalcs = new SicknessCalculations();

            for (HousekeepingTask task : tasks) {
                
                LOGGER.log(Level.INFO, "Housekeeping {0} Started", task);
                
                switch (task) {

                    case CLOCKED_TIME:
                        ClockedTime.reassessClockedTime(entityManager, range);
                        break;

                    case HOLIDAY:
                        holidayCalcs.reassessHolidays(entityManager);
                        break;

                    case SICKNESS:
                        sicknessCalcs.reassessSickness(entityManager);
                        break;

                    case HOLIDAY_SUMMARY:
                        holidayCalcs.reassessSummaries(entityManager);
                        break;
                        
                    case SICKNESS_SUMMARY:
                        sicknessCalcs.reassessSummaries(entityManager);
                        break;

                    case TIMESHEET:
                        TimesheetMaintenance.performAllHousekeeping(entityManager);
                        break;

                    case ALLOCATED_TIME:
                        PeriodCalculations.reassessAndPersistWorkingDays(entityManager, range);
                        break;

                    case MONTH_END:
                        MonthEndCalculations.processMonthEnd(entityManager);
                }
                
                LOGGER.log(Level.INFO, "Housekeeping {0} Completed", task);
            }
            
            // Commit changes to database

            entityManager.getTransaction().commit();

        } catch (RuntimeException ex) {

            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }

            // If an error is encountered then rollback the transaction
            // and cascade the root cause back to the caller

            LOGGER.log(Level.SEVERE, "Error performing startup housekeeping", ex);
            ErrorDialog.showError(this.getFrame(), ex);
            
        } finally {
            getFrame().setCursor(savedCursor);
        }

        LOGGER.info("Housekeeping Completed");
    }

    @Action
    public void reassessAllData() {
        
        SelectDateRangeDialog dateRangeDialog = new SelectDateRangeDialog(
                this.getFrame(), Control.getActiveWindow(entityManager));

        dateRangeDialog.setVisible(true);

        if (dateRangeDialog.ok()) {
            performHousekeeping(
                    dateRangeDialog.getDateRange(),
                    HousekeepingTask.values());
        }
    }

    @Action
    public void reassessHolidays() {
        performHousekeeping(null,
                HousekeepingTask.HOLIDAY,
                HousekeepingTask.HOLIDAY_SUMMARY);
    }

    @Action
    public void reassessSickness() {
        performHousekeeping(null,
                HousekeepingTask.SICKNESS,
                HousekeepingTask.SICKNESS_SUMMARY);
    }

    @Action
    public void reassessClockedTime() {

        SelectDateRangeDialog dateRangeDialog = new SelectDateRangeDialog(
                this.getFrame(), Control.getActiveWindow(entityManager));
        
        dateRangeDialog.setVisible(true);

        if (dateRangeDialog.ok()) {
            performHousekeeping(
                    dateRangeDialog.getDateRange(),
                    HousekeepingTask.CLOCKED_TIME);
        }
    }

    @Action
    public void reassessAllocatedTime() {
        performHousekeeping(null,
                HousekeepingTask.TIMESHEET,
                HousekeepingTask.ALLOCATED_TIME);
    }

    @Action
    public void reassesMonthEnd() {
        performHousekeeping(Control.getActiveWindow(entityManager),
                HousekeepingTask.MONTH_END);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenu absenceReportMenu;
    private javax.swing.JButton acknowledgeButton;
    private javax.swing.JMenuItem allocatedHours;
    private javax.swing.JMenuItem anomaliesReportMenuItem;
    private javax.swing.JMenuItem anyDatesCollatedTimeAll;
    private javax.swing.JMenuItem anyDatesCollatedTimeSalaried;
    private javax.swing.JMenuItem anyDatesCollatedTimeSessional;
    private javax.swing.JMenuItem anyMonthCollatedTimeAll;
    private javax.swing.JMenuItem anyMonthCollatedTimeSalaried;
    private javax.swing.JMenuItem anyMonthCollatedTimeSessional;
    private javax.swing.JMenuItem anyWeekTimesheetReport;
    private javax.swing.JToggleButton badgesToggle;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JMenuItem chooseMonthReportItem;
    private javax.swing.JMenuItem chooseMonthSummary;
    private javax.swing.JMenuItem chooseWeekReportItem;
    private javax.swing.JMenuItem chooseYearReportItem;
    private javax.swing.JMenuItem clockedTime;
    private javax.swing.JToggleButton clockedTimesToggle;
    private javax.swing.JMenu collatedTimeAllReportMenu;
    private javax.swing.JMenu collatedTimeSalariedReportMenu;
    private javax.swing.JMenu collatedTimeSessionalReportMenu;
    private javax.swing.JRadioButtonMenuItem configMenuItem;
    private javax.swing.JMenuItem employeeReportMenu;
    private javax.swing.JToggleButton employeesToggle;
    private javax.swing.JMenu errorLoggingMenu;
    private javax.swing.JPanel eventLogPanel;
    private javax.swing.JMenuItem executeAlertCheckMenuItem;
    private javax.swing.JSeparator fileSeparator1;
    private javax.swing.JRadioButtonMenuItem fineMenuItem;
    private javax.swing.JRadioButtonMenuItem finerMenuItem;
    private javax.swing.JRadioButtonMenuItem finestMenuItem;
    private javax.swing.JToggleButton holidayAdjustmentToggle;
    private javax.swing.JToggleButton holidayRequestToggle;
    private javax.swing.JRadioButtonMenuItem infoMenuItem;
    private javax.swing.JButton jButton1;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem1;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem2;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem lastMonthCollatedTimeAll;
    private javax.swing.JMenuItem lastMonthCollatedTimeSalaried;
    private javax.swing.JMenuItem lastMonthCollatedTimeSessional;
    private javax.swing.JMenuItem lastMonthReportItem;
    private javax.swing.JMenuItem lastMonthSummary;
    private javax.swing.JMenuItem lastWeekReportItem;
    private javax.swing.JMenuItem lastWeekTimesheetReport;
    private javax.swing.ButtonGroup loggingLevelGroup;
    private javax.swing.JButton logoutButton;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JScrollPane masterScrollPane;
    private javax.swing.JTable masterTable;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem monthEnd;
    private javax.swing.JMenuItem monthEndCloseOffMenuItem;
    private javax.swing.JMenu monthEndMenu;
    private javax.swing.JMenuItem monthEndSummaryReportMenuItem;
    private javax.swing.JToggleButton monthEndToggle;
    private javax.swing.JMenu monthReportMenu;
    private javax.swing.JMenu monthlySummaryReportMenu;
    private javax.swing.JMenuItem nextMonthReportItem;
    private javax.swing.JMenuItem nextWeekReportItem;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JMenuItem refreshAll;
    private javax.swing.JMenuItem refreshHolidays;
    private javax.swing.JMenu refreshMenu;
    private javax.swing.JMenuItem refreshSickness;
    private javax.swing.JMenu reportsMenu;
    private javax.swing.JToggleButton sessionsToggle;
    private javax.swing.JMenuItem setLoggingFolderItem;
    private javax.swing.JRadioButtonMenuItem severeMenuItem;
    private javax.swing.JToggleButton showAllButton;
    private javax.swing.JToggleButton sicknessReportToggle;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JMenuItem thisMonthCollatedTimeAll;
    private javax.swing.JMenuItem thisMonthCollatedTimeSalaried;
    private javax.swing.JMenuItem thisMonthCollatedTimeSessional;
    private javax.swing.JMenuItem thisMonthReportItem;
    private javax.swing.JMenuItem thisMonthSummary;
    private javax.swing.JMenuItem thisWeekReportItem;
    private javax.swing.JMenuItem thisWeekTimesheetReport;
    private javax.swing.JMenuItem thisYearReportItem;
    private javax.swing.JMenuItem thisYearReportItem1;
    private javax.swing.JMenuItem thisYearReportItem2;
    private javax.swing.JToolBar timeRecordingToolBar;
    private javax.swing.JMenu timesheetReportMenu;
    private javax.swing.JToggleButton timesheetsToggle;
    private javax.swing.JMenu toolsMenu;
    private javax.swing.JSeparator toolsSeparator;
    private javax.swing.JPopupMenu.Separator toolsSeparator1;
    private javax.swing.JRadioButtonMenuItem warningMenuItem;
    private javax.swing.JMenu weekReportMenu;
    private javax.swing.JMenu yearReportMenu;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    // My private variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;
    private LoginDialog loginDialog;
    private boolean bLoggedIn = false;
    private JDialog employeesDialog;
    private JDialog badgesDialog;
    private JDialog holidayAdjustmentDialog;
    private JDialog holidayRequestDialog;
    private JDialog sicknessReportDialog;
    private JDialog timesheetsDialog;
    private JDialog monthEndDialog;
    private JDialog clockedTimesDialog;
    private JDialog sessionsDialog;
    private final Application myApp;
}
